home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-08-15 | 65.7 KB | 2,102 lines |
- NAME MSZRMX
- true equ 1
- escbslh equ 5c1bh ; ESC \
- escbrac equ 5d1bh ; ESC ]
- $INCLUDE(mssdef.h86)
-
- %*DEFINE(pushv(v))(%IF(%OS EQ 286)THEN(push %v)ELSE(mov ax,%v
- push ax)FI)
-
- datas segment
-
- public citok, cotok, mbox, tmbox, sigpair, sematok, bufill, ciptr
- public cifill, cibuf1, cibuf2, combx, cimbx, termatt, oneport
- public subpksz, trok, source, trmstr, temp, machnam
-
- extrn sintok:word, srcptr:word, takadr:word, taklev:byte, comand:byte
- extrn portval:word, savsi:word, xofsnt:byte, portatt:word
- extrn costrt:word, coptr:word, flags:byte, pack:byte, dtrtime:word
- extrn bdtab:byte, bddat:word
-
- env db 0,0 ; "environment" must be on PARA boundary
- machnam db 21 dup(' ')
- trmstr db 6,':TERM:'
- lp db 4,':LP:'
- bb db 4,':BB:'
- work db 6,':WORK:'
- dolsgn db 1,'$'
- rqglob db 8,'RQGLOBAL'
- dotini db 'MSKERMIT.INI',0
- kermtmp db '$kermit$.tmp ',0 ; Kermit's DOS name for scratch file
-
- sigpair dw 0
- db 3 ; control C
-
- kilpair dw 0
- db 0
-
- setosc db ESCAPE,']C:T=1,E=1,R=1,O=1,C=2;T:R=1',ESCAPE,'\'
- flush db ESCAPE,']C:T=3',ESCAPE,'\'
- escapec db ESCAPE,'c'
- printer db 'PRN',0
- typecmd db 'type '
- delcmd db 'del '
- chkdsk db 'chkdsk.com'
- dirfree db 'dir $ free',cr
-
- delrmx db 'delete ' ; keep these 2 lines together
- deltail db 73 dup(?)
-
- wccmd db 0,'WC ' ; keep these 2 lines together
- wcpath db 80 dup(?)
-
- pushmsg db cr,lf,'PUSH not implemented, use RUN whatever$'
- syserr db cr,lf,'Your version of MSKERMIT used an unsupported DOS '
- db 'function call'
- crlf db cr,lf,'$'
- cfgerr db cr,lf,'Configuration error',cr,lf,'$'
- killmsg db cr,lf,'Only 1st KILL accepted',cr,lf,'$'
- mbmsg db cr,lf,'MAX-BAUD error',cr,lf,'$'
- oscmsg db cr,lf,'OSC error',cr,lf,'$'
- prmsg db cr,lf,'Priority error',cr,lf,'$'
- nmsg db cr,lf,'Number > 0ffh',cr,lf,'$'
- dnmsg db cr,lf,'Must be decimal number',cr,lf,'$'
- nxtflg db 1
- oneport db 0
- codone db ?
- esc_c db 0
- trok db 0
-
- $SAVE NOGEN
- comtab db 13
- %mkeyw (%('bufill'),fillbuf)
- %mkeyw (%('cifill'),fillci)
- %mkeyw (%('co-delay'),codel)
- %mkeyw (%('dtr-time'),dtr)
- %mkeyw (%('echo'),takset)
- %mkeyw (%('escc'),esccset)
- %mkeyw (%('kill'),kill)
- %mkeyw (%('max-baud'),maxbd)
- %mkeyw (%('no-modem'),nomdm)
- %mkeyw (%('osc'),osc)
- %mkeyw (%('priority'),prior)
- %mkeyw (%('sub-pack'),subpack)
- %mkeyw (%('translate'),trnslt)
- $RESTORE
-
- even
- citok dw ? ; DON'T reorder citok, cotok, lptok lines
- cotok dw 3 dup (?)
- lptok dw ?
-
-
- sematok dw ?
- initok dw 0
- globtok dw ?
- doltok dw ?
- scfitok dw ?
- rcmdtok dw ?
- mbox dw ?
- tmbox dw ?
- cimbx dw ?
- combx dw ?
- kbuf dw ?
- cmdtok dw ?
- xitcode dw 40ffh
- savebx dw ?
- status dw ?
- ccstat dw ?
- siostat dw ?
- priorty dw 254
- bufill dw 0ffffh
- cifill dw 8080h
- subpksz dw 60
- codelay dw 6
- ciptr dw offset cibuf1
- cistrt dw ?
- inisize dw ?
- savspec dw 12,12,12 dup (0)
- termatt dw 2,2,2 dup (?) ; terminal port attributes for special
- ignore dw ?
- xcepinf dw 3 dup (0)
-
- temp dw 110 dup(?)
- org offset temp
- db 'Copyright 1988, John Bryans.'
- db 'Permission is granted to copy and give away,'
- db 'but not to sell for profit any form of this program.'
- db 'No Warranties Whatsoever'
- org offset temp+size temp
-
- cibuf1 db cibufl dup (?)
- cibuf2 db cibufl dup (?)
- cobuf1 db cobufl dup (?)
- cobuf2 db cobufl dup (?)
-
- source db bufsiz dup(0) ; serial input buffer
-
- PURGE conin,conout,lstout,dconio,coninq,prstr,seldsk,gcurdsk,setdma,gettim
- PURGE dosver,gswitch,chdir,creat2,open2,close2,readf2,write2,del2,lseek,gcd
- PURGE alloc,setblk,exec,first2,next2
-
- dosf dw notimp ; DOS function call jump table
- dw conin
- dw conout
- dw 2 dup(notimp)
- dw lstout
- dw dconio
- dw coninq
- dw rkbd
- dw prstr
- dw 4 dup(notimp)
- dw seldsk
- dw 10 dup(notimp)
- dw gcurdsk
- dw setdma
- dw 10 dup(notimp)
- dw setintv
- dw 6 dup(notimp)
- dw gettim
- dw 3 dup(notimp)
- dw dosver
- dw 4 dup(notimp)
- dw getintv
- dw notimp
- dw gswitch
- dw 3 dup(notimp)
- dw chdir
- dw creat2
- dw open2
- dw close2
- dw readf2
- dw write2
- dw del2
- dw lseek
- dw 4 dup(notimp)
- dw gcd
- dw alloc
- dw notimp
- dw setblk
- dw exec
- dw exit
- dw notimp
- dw first2
- dw next2
- dosfl equ ($-dosf-2)/2
-
- datas ends
- %IF (%OS EQ 86) THEN (
- stack segment stack 'stack'
- dw 750 dup(?)
- stack ends
- ) ELSE (
- stack stackseg 1500
- )FI
- code segment
- public dosint, crfile, opfile, special, writer, delcon, prstr, dconio
- public aopen, aclose, awrite, aspcl, waitio, sendms, rcvmsg, delseg
- public gfilsta, flushci
-
- extrn start:near, outchr:near, takrd:near, prompt:near, comnd:near
- extrn takset:near, atoi:near, katoi:near
-
- extrn dqdecodetime:near, dqgetsystemid:near
-
- extrn rqcgetchar:near, rqcgetcommandname:near
- extrn rqccreatecommandconnection:near, rqcsendcommand:near
-
- extrn rqsopen:near, rqsdeleteconnection:near, rqsattachfile:near
- extrn rqsreadmove:near, rqsseek:near, rqsgetconnectionstatus:near
- extrn rqscreatefile:near, rqswritemove:near, rqsspecial:near
- extrn rqsgetfilestatus:near, rqsdeletefile:near, rqsclose:near
- extrn rqstruncatefile:near, rqexitiojob:near
-
- extrn rqaopen:near, rqaclose:near, rqaread:near, rqawrite:near
- extrn rqwaitio:near, rqaspecial:near, rqsetdefaultprefix:near
-
- extrn rqsetexceptionhandler:near, rqsetpriority:near
- extrn rqcreatesemaphore:near, rqreceiveunits:near, rqcreatetask:near
- extrn rqcreatemailbox:near, rqreceivemessage:near, rqsendmessage:near
- extrn rqcreatesegment:near, rqdeletesegment:near, rqlookupobject:near
- %IF (%OS EQ 286) THEN (
- extrn rqegetaddress:near, rqecreatedescriptor:near
- extrn rqedeletedescriptor:near
- )FI
- psp: jmp stop ; "program segment prefix"
- db 10h ; combined w/previous byte makes size>65K
- db 0
- db 9ah,0f0h,0ffh,0dh,0f0h ; beats the hell out of me
- dd quitint ; termination address
- dd cctask ; control-break address
- dd quitint ; critical error address
- db (psp+2ch)-$ dup(?)
- dw seg env ; segment address of environment
- db (psp+50h)-$ dup(?)
- fake proc far
- jmp dosint ; DOS function dispatcher entry
- fake endp
- db (psp+80h)-$ dup(?)
- cline db 82 dup(0)
-
- begin proc far
- call setexcp
- %IF (%OS EQ 286) THEN (
- push cs
- push offset psp
- push ds
- push offset status
- call rqegetaddress
- push dx
- push ax
- push offset begin
- push ds
- push offset status
- call rqecreatedescriptor
- )ELSE(
- mov ax,cs
- )FI
- mov es,ax
- mov di,offset cline ; move command line to cline
- sub al,al
- L1: inc byte ptr es:cline
- stosb ; clears count 1st time thru
- push es ; save es & di
- push di
- push ds ; al=call rqcgetchar(@status)
- %pushv(offset status)
- call rqcgetchar
- pop di ; restore es & di
- pop es
- test al,al ; end of string?
- jnz L1 ; no
- mov byte ptr es:[di],cr ; stuff cr
- %IF (%OS EQ 286) THEN (
- push es ; let's not leave this descriptor laying around
- push ds
- push offset status
- call rqedeletedescriptor)FI
-
- call crmbx ; mbox=rqcreatemailbox(0,@status)
- mov mbox,ax
- call crmbx ; tmbox=rqcreatemailbox(0,@status)
- mov tmbox,ax
- call crmbx ; combx=rqcreatemailbox(0,@status)
- mov combx,ax
- call crmbx ; cimbx=rqcreatemailbox(0,@status)
- mov cimbx,ax
-
- mov di,offset work ; scfitok=rqscreatefile(@(6,':WORK:'),@status)
- call crfile ; scratch file is for wild card implementation
- mov scfitok,ax ; (FIRST2 & NEXT2), and :CO: redirection (EXEC)
-
- mov bx,3 ; call rqsopen(scfitok,3,2,@status)
- mov cx,2
- call opfile
-
- mov di,offset trmstr
- call crfile
- mov citok,ax ; citok=rqscreatefile(@(4,':TERM:'),@status)
-
- mov bx,3 ; call rqaopen(citok,3,3,0,@status)
- call aopen
-
- mov di,offset trmstr
- call crfile
- mov cotok,ax ; cotok=rqscreatefile(@(4,':TERM:'),@status)
- mov cotok+2,ax
- mov cotok+4,ax
-
- mov bx,3 ; call rqsopen(cotok,3,3,@status)
- mov cx,bx
- call opfile
-
- mov ax,cotok ; call rqsspecial(cotok,4,@savspec,0,@status)
- mov bx,offset savspec
- mov cx,4
- call special
- test savspec+18,8000h
- js L2
- mov word ptr savspec+2,7
-
- L2: mov ax,citok ; set OSCs for :CI:
- mov bx,offset setosc
- mov cx,size setosc
- sub dx,dx
- call awrite
-
- mov ax,cotok ; set OSCs for :CO:
- mov bx,offset setosc
- mov cx,size setosc
- call writer
-
- mov ax,citok ; rumor has it write before read
- mov bx,offset crlf ; is s'posed to convince Terminal Support Code
- mov cx,2 ; we're serious about wanting transparent input
- mov dx,tmbox
- call awrite
-
- push ds ; get pathname that called us
- %pushv(offset cobuf1) ; stash @cobuf1
- %pushv(size cobuf1) ; call rqgetcommandname
- push ds ; (@cobuf1,size cobuf1,@status)
- %pushv(offset status)
- call rqcgetcommandname
-
- mov ax,citok ; wait for TSC to settle down
- mov bx,tmbox ; necessary for 386's & lickety-split 286's
- call waitio
-
- mov ax,ds ; back scan to last path separator
- mov es,ax
- mov bl,cobuf1
- sub bh,bh
- lea si,cobuf1[bx]
- call bakscan ; si=file name ptr, bx=its length, al=separator
-
- ; The full string @cobuf1 is used to look for .cfg & .ini in the dir from which
- ; Kermit was loaded. The mid-string, @si-1, is used to look in :$:.
-
- mov [bx+si],'c.' ; catenate '.cfg'
- mov [bx+si+2],'gf'
- dec si ; byte before file name for string count
- mov word ptr cobuf2,si ; save ptr
- add cobuf1,4 ; bump length of full string for .cfg
- add bl,4 ; bump length of mid-string
- mov [si],bl ; RMX string for lookup in :$:
- mov ah,bl ; ah=current byte @si, al=old char @si
- cmp si,offset cobuf1 ; if no path, use bl for old char
- jne L3
- mov al,bl ; instead of the one from bakscan
- L3: mov word ptr cobuf2+2,ax ; save them
-
- call cfgini ; look for .cfg, open, size to dx:si
- jcxz L4 ; OK?
- jmp short L7 ; no, do .ini
- L4: inc taklev
- add takadr,size takinfo
- mov di,takadr
- mov [di].takhnd,ax ; token
- mov [di].taktyp,0feh ; mark as take
- mov [di].takcnt,si ; low size
- mov [di].takcnt+2,dx ; high size
- call takrd
-
- L5: mov ax,ds
- mov es,ax
- mov dx,offset dolsgn ; ptr for prompt
- call prompt
- cmp taklev,0 ; done?
- je L7 ; eq = yes
- mov dx,offset comtab ; command table ptr
- mov bx,offset dolsgn ; help ptr
- mov comand.cmcr,1
- mov ah,cmkey
- call comnd
- jmp short L6 ; error exit
- nop
- call bx ; call cfg s/r
- jmp L5 ; loop
-
- L6: mov dx,offset cfgerr ; output error msg & loop
- call prstr
- jmp L5
-
- L7: mov si,word ptr cobuf2 ; point to mid-string
- mov ax,word ptr cobuf2+2 ; ah=mid-string count, al=path separator
- mov [si],ah
- mov bl,ah
- sub bh,bh
- mov byte ptr[bx+si],'i' ; replace 'cfg' w/'ini'
- dec bx
- dec bx
- mov [bx+si],'ni'
- call cfgini ; look for .ini, open, size to dx:si
- jcxz L8 ; found
- jmp short L9 ; not found
-
- CFGINI proc
- mov di,si
- mov temp,si ; save string pointer
- call atfile ; attach from :$:
- jcxz CGIN1 ; z=found
- mov si,word ptr cobuf2 ; point to mid-string
- mov ax,word ptr cobuf2+2 ; al=path separator
- mov [si],al ; put it back
- mov di,offset cobuf1 ; point to full path
- mov temp,di ; save string pointer
- call atfile ; attach from full path
- jcxz CGIN1
- ret
- CGIN1: mov temp+100,ax ; save token
- mov bx,1
- mov cx,bx
- call opfile ; open for reading
- jcxz CGIN2
- ret
- CGIN2: mov di,temp ; string pointer
- call gfilsta ; get file status to find size
- mov si,ax ; low order file size
- mov ax,temp+100 ; token
- ret
- CFGINI endp
-
- L8: mov inisize,si ; size of .ini
- mov initok,ax ; close KERMIT.INI,
- call clfile ; but leave attached for open2
-
- L9: mov ax,cotok ; save configured attributes
- mov bx,offset termatt ; for ping-ponging
- mov cx,4
- call special
-
- call crsema ; sematok=rqcreatesemaphore(0,1,0,@statu
- mov sematok,ax
- mov sigpair,ax ; for ^C trapping
-
- mov ax,citok ; establish ^C & sematok as signal pair
- mov cx,6
- mov bx,offset sigpair
- call aspcl
-
- mov bx,offset cctask ; call rqcreatetask
- call crtsk ; (0,@cctask,datas,0,300,0,@status)
-
- mov bx,offset siotsk ; call rqcreatetask
- call crtsk ; (0,@siotsk,datas,0,300,0,@status)
-
- mov bx,offset citsk ; call rqcreatetask
- call crtsk ; (0,@citsk,datas,0,300,0,@status)
-
- mov bx,offset cotsk ; call rqcreatetask
- call crtsk ; (0,@cotsk,datas,0,300,0,@status)
-
- mov di,offset lp ; lptok=rqscreatefile(@(4,':LP:'),@status)
- call crfile
- jcxz L10 ; jump if OK
- mov di,offset bb ; otherwise use :BB:
- call crfile
- L10: mov lptok,ax
-
- mov bx,2 ; call rqsopen(lptok,2,2,@status)
- mov cx,bx
- call opfile
-
- mov ax,citok ; cmdtok = rqccreatecommandconnection(citok,
- mov bx,cotok ; cotok,0,@status)
- sub cx,cx
- call crcmdco
- mov cmdtok,ax
-
- mov ax,lptok ; rcmdtok = rqccreatecommandconnection(lptok,
- mov bx,scfitok ; scfitok,1,@status)
- mov cx,1 ; lptok forces error if ":CI:" gets read,
- call crcmdco ; scfitok is ":CO:" redirected to scratch file
- mov rcmdtok,ax
-
- push ds ; call dqgetsystemid(@temp,@status)
- %pushv(offset temp)
- push ds
- %pushv(offset status)
- call dqgetsystemid
- mov ax,ds ; use system id for machine name
- mov es,ax
- mov si,offset temp+1
- mov di,offset machnam
- mov cl,byte ptr temp
- sub ch,ch
- rep movsb
- mov al,'$' ; it's a $ terminated string
- stosb
-
- mov ax,cx
- mov bx,offset rqglob
- call lookup ; globtok=rqlookupobject(0,@rqglob,0,@status)
- mov globtok,ax
-
- mov bx,offset dolsgn
- call lookup ; doltok=rqlookupobject(globtok,@dolsgn,0,@statu
- mov doltok,ax
-
- push cx ; call rqsetpriority(0,priorty,@status)
- push priorty
- push ds
- %pushv(offset status)
- call rqsetpriority
-
- mov ax,cs
- mov ds,ax ; point ds & es to psp
- mov es,ax
-
- jmp start ; go to Kermit
-
- begin endp
-
- ; cfg subroutines.
- ; Number conversion routines getn & getdn return to caller's caller on error
-
- fillbuf proc
- call getn ; convert backslash number
- mov bufill,ax ; set serial input background fill
- ret
- fillbuf endp
-
- fillci proc
- call getn ; convert backslash number
- mov cifill,ax ; set terminal input background fill
- ret
- fillci endp
-
- codel proc
- call getdn ; convert decimal number
- mov codelay,ax ; set connect mode terminal output buffer time
- ret
- codel endp
-
- dtr proc
- call getdn ; convert decimal number
- mov dtrtime,ax ; set time to hold DTR down
- ret
- dtr endp
-
- esccset proc
- mov esc_c,true ; enable sending ESC c (VT100 reset) on exit
- ret
- esccset endp
-
- kill proc
- call getn ; convert backslash number
- cmp kilpair,0 ; has task already been created?
- jne K1 ; ne = yes
- mov byte ptr kilpair+2,al ; set control char to trap
- call crsema ; kilpair=rqcreatesemaphore(0,1,0,@status)
- mov kilpair,ax
- mov bx,offset kiltsk
- call crtsk ; create kill task
- mov ax,citok
- mov cx,6
- mov bx,offset kilpair
- call aspcl ; establish trap char & kiltsk as signal pair
- ret
- K1: mov dx,offset killmsg ; don't let 'em do it twice
- call prstr
- ret
- kill endp
-
- maxbd proc
- mov dx,offset bdtab ; parse for baud rate
- sub bx,bx
- mov ah,cmkey
- call comnd
- jmp short MB1 ; NG, bitch
- nop
- mov temp,bx ; save baud ix
- mov ah,cmcfm ; proper parsing ettiqutte
- call comnd
- jmp short MB1 ; NG, bitch
- nop
- mov bx,temp ; baud ix
- inc bx ; next higher
- mov cx,baudsiz ; baudsiz - (1+baud ix) is # wds to clear
- sub cx,bx ; x2 is word ix
- shl bx,1
- mov ax,ds
- mov es,ax
- sub ax,ax
- mov di,offset bddat ; point to 1st word to clear
- add di,bx
- cld
- rep stosw ; wipe 'em out
- ret
- MB1: mov dx,offset mbmsg
- call prstr
- ret
- maxbd endp
-
- nomdm proc
- and portatt+6,0fff7h ; turn off modem control bit
- ret
- nomdm endp
-
- osc proc
- mov ah,cmtxt ; parse text upto cr to temp+2
- mov bx,offset temp+2
- mov dx,offset dolsgn
- call comnd
- jmp short OSCERR ; NG
- nop
- mov cl,ah
- sub ch,ch ; cx = # bytes
- mov di,offset temp+2 ; point to start
- mov ax,ds
- mov es,ax
- mov al,' '
- cld
- repe scasb ; discard leading blanks
- je OSCERR ; empty, show indignation
- xchg bx,di ; bx = 1st non-blank char ptr
- dec di ; di = last char ptr
- std
- repe scasb ; discard trailing blanks
- cld
- add cl,6 ; cx = total length of OSC
- inc di
- inc di ; point to plant trailer
- sub bx,3 ; point to plant lead-in
- mov [bx],escbrac ; insert lead-in
- mov [di],escbslh ; insert trailer
- mov ax,cotok
- push bx ; save ptr for ci
- push cx ; save count for ci
- call writer ; write OSC to cotok
- pop cx
- pop bx
- mov ax,citok ; write OSC to citok
- sub dx,dx
- call awrite
- ret
- OSCERR: mov dx,offset oscmsg
- call prstr
- ret
- osc endp
-
- prior proc
- call getn ; convert backslash number
- je PRERR ; getn compared to 255, reject if =
- mov byte ptr priorty,al ; set priority
- ret
- PRERR: mov dx,offset prmsg
- call prstr
- ret
- prior endp
-
- subpack proc
- call getdn ; convert decimal number
- mov subpksz,ax ; set sub-packet size (tuning param for sending)
- ret
- subpack endp
-
- trnslt proc
- mov trok,true ; enable translation during connect
- ret
- trnslt endp
-
- getn proc ; bags backslash #, converts it, ensures<256, returns in ah & al
- mov ah,cmfile ; parse upto whitespace into temp
- mov bx,offset dolsgn
- mov dx,offset temp
- mov byte ptr temp,0
- call comnd
- jmp short NERR ; NG return
- nop
- mov si,offset temp ; point to it
- call katoi ; convert it
- jc NERR ; carry set = NG
- cmp ax,0ffh ; we want 255 max
- ja NERR
- mov ah,al ; both bytes the same for word filling
- ret
- NERR: mov dx,offset nmsg
- call prstr
- pop ax
- ret
- getn endp
-
- getdn proc ; bags decimal number, converts it, returns it in ax
- mov ah,cmtxt ; parse upto cr into temp
- mov bx,offset temp
- mov dx,offset dolsgn
- mov byte ptr[bx],0
- call comnd
- jmp short DNERR ; NG return
- nop
- mov si,offset temp ; point to it
- call atoi ; convert it
- jmp short DNERR ; NG return
- nop
- ret ; got it, it's in ax
- DNERR: mov dx,offset dnmsg
- call prstr
- pop ax
- ret
- getdn endp
-
- dosint proc ; DOS function call table look up
- push ds
- push bx
- mov bx,datas
- mov ds,bx
- pop savebx
- cmp ah,dosfl
- ja notimp
- sub bh,bh
- mov bl,ah
- rol bx,1
- call dosf[bx]
- mov bx,savebx
- pop ds
- ret
- dosint endp
-
- notimp: ; not implemented DOS function error routine
- mov dx,offset syserr
- call prstr
-
- quitint proc far
- stop: mov ax,datas
- mov ds,ax
- mov dx,offset crlf
- call prstr
-
- cmp esc_c,true ; is ESC c cfg'd?
- jne ST1 ; ne = no
- mov ax,cotok ; give Terminal Support Code an ESC c
- mov bx,offset escapec ; to restore terminal to initial state
- mov cx,size escapec
- call writer
-
- ST1: mov ax,cotok ; close to wait for output completion
- call clfile
- mov ax,citok ; restore terminal attributes
- mov bx,offset savspec
- mov cx,5
- call aspcl
-
- mov cx,globtok ; restore $ directory
- mov ax,doltok ; call rqsetdefaultprefix(globtok,doltok,@status
- call sdefpfx
-
- mov cx,kilpair ; was a kill kermit ctrl char established
- jcxz ST2 ; z = no
- mov ax,citok ; yes, disestablish
- mov bx,offset kilpair
- mov word ptr[bx],0
- mov cx,6
- call aspcl
-
- ST2: mov ax,citok ; wait for completion before exit
- mov cx,tmbox
- call aclose
- mov ax,tmbox
- mov bx,0ffffh
- call rcvmsg
-
- push xitcode ; call rqexitiojob(xitcode,@0,@status)
- sub ax,ax
- push ax
- push ax
- push ds
- %pushv(offset status)
- call rqexitiojob
- quitint endp
-
- kiltsk proc ; kill task
- mov ax,kilpair ; wait for kill char to be typed
- call rcvun
- jmp STOP ; then quit
- kiltsk endp
-
- cctask proc far ; ^C task
- CCT: mov ax,sematok ; wait for ^C to be typed
- call rcvun
- mov flags.cxzflg,'C' ; slightly adapted (mostly stolen) from
- mov pack.state,'A' ; MSSKER's intbrk
- jmp CCT
- cctask endp
-
- siotsk proc far ; serial input task
- call setexcp ; never call exception handler
- SIO1: mov bx,0ffffh ; wait forever @ mbox for something to do
- SIO2: mov ax,mbox
- call rcvmsg
- cmp ax,mbox ; if it's the token for mbox,
- je SIO6 ; it's SERINI asking us to crank up input
- dec cx ; otherwise it's E$TIME or an IORS
- jz SIO3 ; it's E$TIME
- call delseg ; it's an IORS, so delete it
- SIO3: cmp sintok,0 ; if the port has been reset,
- je SIO1 ; let the interrupts expire unanswered
- cmp xofsnt,true
- jne SIO4
- mov bx,50
- jmp SIO2
- SIO4: call sread ; start aread & fill following buffer quadrant
- mov ax,srcptr
- sub ax,savsi ; if there's at least 2 quadrants between next
- jns SIO5 ; quadrant & current pointer,
- add ax,bufsiz
- SIO5: cmp ax,bufsiz/2
- jle SIO1 ; we don't need to XOF, so wait for interrupt
- mov bx,portval
- cmp [bx].floflg,0 ; is flow control enabled?
- je SIO1 ; no
- mov ax,[bx].flowc ; ouput whatever we're using for XOF
- mov ah,al
- call outchr
- nop
- nop
- nop
- mov xofsnt,true
- jmp SIO1
- SIO6: mov ax,sintok ; for aspecial to set it
- mov bx,offset portatt
- or word ptr[bx+4],3 ; change to flushing mode
- mov cx,5 ; while we're at it
- call aspcl
- SIO7: mov ax,sintok
- mov bx,offset source ; initialize
- mov savsi,bx ; current byte ptr
- mov srcptr,bx ; & next quadrant ptr
- mov cx,bufsiz ; in case the ports on a buffered board
- mov dx,mbox ; flush it's buffer
- call aread
- mov ax,sintok
- mov bx,mbox
- call waitio
- cmp ax,bufsiz
- je SIO7 ; no matter how big the damn thing is
- mov ax,sintok
- mov bx,offset portatt
- and word ptr[bx+4],0fffdh ; change back to transparent mode
- mov cx,5
- call aspcl
- mov ax,ds ; fill 1st quadrant
- mov es,ax
- mov ax,bufill
- mov cx,bufsiz/8
- mov di,offset source
- cld
- rep stosw
- call sread ; start 1st read & fill 2nd quadrant
- jmp SIO4 ; go do 2nd read
-
- sread proc
- mov ax,sintok
- mov bx,srcptr ; next quadrant ptr
- mov cx,bufsiz/4
- mov dx,mbox
- call aread ; read current quadrant
- mov ax,ds
- mov es,ax
- mov ax,bufill
- mov cx,bufsiz/4
- mov di,srcptr
- add di,cx
- cmp di,bufsiz+offset source ; was it last quadrant
- jl SRD1 ; no
- mov di,offset source ; yes, point to 1st
- SRD1: mov srcptr,di ; set next quadrant ptr
- shr cx,1
- cld
- rep stosw ; fill quadrant
- ret
- sread endp
- siotsk endp
-
- citsk proc far ; read terminal task
- call setexcp
- CIT1: mov bx,offset cibuf1
- CIT2: mov cistrt,bx ; set buffer ptr
-
- mov ax,ds ; fill it w/cifill
- mov es,ax
- mov di,bx
- mov cx,(size cibuf1)/2
- mov ax,cifill
- cld
- rep stosw
-
- mov ax,citok ; call rqaread
- mov cx,size cibuf1 ; (citok,@buffer,size(buffer),cimbx,@statu
- mov dx,cimbx
- call aread
-
- CIT3: mov ax,cimbx ; wait for completion or task restart
- mov bx,0ffffh
- call rcvmsg
-
- cmp ax,cimbx ; if it's the mail box token, it's task restart
- jne CIT4 ; if, not it's an IORS
- mov bx,offset cibuf1
- mov ciptr,bx ; initialize buffer & char pointers
- jmp CIT2 ; & start over
-
- CIT4: mov es,ax ; check IORS for "flushing" status
- cmp es:word ptr 0,2ch
- pushf
- call delseg ; delete IORS
- popf ; "flushing" means suspend task,
- je CIT3 ; go wait for restart
-
- mov bx,offset cibuf2
- cmp bx,cistrt ; exchange buffers
- je CIT1
- jmp CIT2
- citsk endp
-
- cotsk proc far ; write terminal task -- active in connect mode
- call setexcp
- COT1: mov ax,combx ; wait for task start or IORS
- mov bx,0ffffh
- call rcvmsg
-
- cmp ax,combx ; if it's the mail box token, it's task start
- je COT2
- call delseg ; otherwise it's an expiring IORS, delete it
- jmp COT1 ; & wait for task start
-
- COT2: mov ax,cotok ; task start. close EIOS & re-open BIOS
- call clfile
- mov ax,cotok
- mov bx,2
- mov codone,bl ; mark write complete
- call aopen
-
- COT3: mov ax,offset cobuf1
- COT4: mov coptr,ax ; byte ptr
- mov costrt,ax ; buffer ptr
-
- COT5: mov ax,combx ; wait for timer, IORS, or suspend task request
- mov bx,codelay ; default = 60 milliseconds
- call rcvmsg
- jcxz COT6 ; 0 = IORS or suspend task
- cmp codone,0 ; timeout. Is write complete?
- jne COT7 ; ne = yes
- jmp COT5 ; no, wait for it
-
- COT6: cmp ax,combx ; if mail box token
- je COT9 ; it's suspend task request
- mov codone,true ; it's IORS, mark write complete
- call delseg ; delete IORS
-
- COT7: mov bx,costrt ; buffer ptr
- mov cx,coptr ; byte prt
- sub cx,bx ; # bytes to write
- jcxz COT8 ; don't write 0
- mov ax,cotok ; call rqawrite
- mov dx,combx ; (cotok,@buffer,nbytes,combx,@status)
- call awrite
- mov codone,0 ; mark write not finished
-
- COT8: mov ax,offset cobuf2
- cmp ax,costrt ; exchange buffers
- je COT3
- jmp COT4
-
- COT9: mov ax,cotok ; suspend task. Close BIOS, wait for task start
- call aclose
- jmp COT1
- cotsk endp
-
- conin proc
- call rkbd ; read 1 from :CI: to al
- push dx
- mov dl,al ; conout writes out dl
- call conout ; echo it to :CO:
- pop dx
- ret
- conin endp
-
- conout proc
- call save
- mov ax,cotok ; write dl to :CO:
- CO1: mov cx,1
- mov temp,dx
- mov bx,offset temp
- call writer
- call rstr
- ret
- conout endp
-
- lstout proc
- call save
- mov ax,lptok ; write dl to :LP:
- jmp CO1
- lstout endp
-
- dconio proc
- cmp dl,0ffh ; if dl ain't ff,
- jne conout ; it's same as conout
- push si
- push cx
- call rdci ; read 1 from :CI: to temp, on return
- test cx,cx ; cx=1 if read, 0 if not, set zero flag if not
- pop cx
- pop si
- ret
- dconio endp
-
- coninq proc
- push cx
- DC1: call rdci ; read 1 from :CI: to temp
- jcxz DC1 ; 'til we get 1
- pop cx
- ret
- coninq endp
-
- rkbd proc
- RKBD1: call pollci ; read 1 from :CI: to al
- je RKBD1 ; 'til we get 1
- ret
- rkbd endp
-
- rdci proc
- sub cx,cx
- cmp flags.cxzflg,'C' ; reads 1 from :CI: to temp, doesn't
- jne RDC1 ; wait, doesn't check ^C
- mov flags.cxzflg,ch ; returns cx=1 if read, 0 if not
- mov al,3
- jmp short RDC2
- RDC1: call pollci
- je RDC3
- RDC2: inc cx
- RDC3: ret
- rdci endp
-
- pollci proc
- push si
- cmp sintok,0 ; if serial port's active
- je PCI1
- cmp oneport,true ; & oneport
- je PCI3 ; return no character
-
- PCI1: mov si,ciptr ; next byte ptr
- lodsb
- cmp al,byte ptr cifill
- je PCI3 ; eq = no byte
- cmp si,offset cibuf2 + size cibuf2
- jne PCI2
- mov si,offset cibuf1
- test si,si ; clear equal
- PCI2: mov ciptr,si ; set ptr for next byte
- PCI3: pop si
- ret
- pollci endp
-
- prstr proc
- call save ; call rqswritemove(cotok,ds:dx,#char,@status)
- mov ax,ds
- mov es,ax
- mov di,dx
- mov cx,0ffffh
- mov al,'$'
- repne scasb
- neg cx
- add cx,0fffeh ; cx=#characters
- jcxz PRSTR1 ; why bother
- mov ax,cotok
- mov bx,dx
- call writer
- PRSTR1: call rstr
- ret
- prstr endp
-
- seldsk proc
- mov al,1 ; what the hell, say there's 1
- ret
- seldsk endp
-
- gcurdsk proc
- sub al,al ; always A: -- meaningless anyway
- ret
- gcurdsk endp
-
- setdma proc
- mov kbuf,dx ; save disk transfer address, DTA
- ret
- setdma endp
-
- setintv proc
- ret ; if KERMIT ever does more than
- setintv endp ; setup int 23h, we're in trouble
-
- gettim proc
- call save
- sub ax,ax ; let dword @temp be system time
- mov temp,ax ; set to 0, so decodetime returns current time
- mov temp+2,ax
- push ds ; call dqdecodetime(@temp,@status)
- %pushv(offset temp)
- push ds
- %pushv(offset status)
- call dqdecodetime
- call rstr
- push ax
- mov dx,temp+12
- call asc2bin
- mov ch,dl ; ch=hours
- mov dx,temp+15
- call asc2bin
- mov cl,dl ; cl=minutes
- mov dx,temp+18
- call asc2bin
- mov dh,dl ; dh=seconds
- sub dl,dl ; dl=0 hundredths
- pop ax
- ret
- asc2bin proc
- sub dx,'00'
- shl dl,1
- mov al,dl
- shl dl,1
- shl dl,1
- add dl,al
- add dl,dh
- ret
- asc2bin endp
- gettim endp
-
- dosver proc
- mov al,2 ; we're simulating DOS 2.x
- ret
- dosver endp
-
- gswitch proc
- mov dl,'/' ; undocumented DOS get switch character
- ret
- gswitch endp
-
- getintv proc
- ret ; if KERMIT ever does more than
- getintv endp ; setup int 23h, we're in trouble
-
- chdir proc
- call save
- mov ax,ds
- mov es,ax
- mov si,offset temp+1
- call z2rmx ; copy ASCIIZ string @ds:dx to temp+1
- mov byte ptr temp,al
- mov di,offset temp ; length to temp makes it RMX string
- call atfile ; attach file
- jcxz CHD2 ; jump if OK
- CHD1: call rstr
- mov ax,3 ; return error code w/carry set
- stc
- ret
- CHD2: mov cx,globtok ; call rqsetdefaultprefix(globtok,ax,@status)
- push ax
- call sdefpfx
- pop ax
- jcxz CHD3
- jmp CHD1
- CHD3: call sdefpfx ; call rqsetdefaultprefix(0,ax,@status)
- call rstr
- clc
- ret
- chdir endp
-
- creat2 proc
- call save
- mov ax,ds
- mov es,ax
- mov si,offset printer ; is it PRN ?
- mov di,dx
- mov cx,size printer
- repe cmpsb
- jne CRF1 ; ne=no
- call rstr
- mov ax,lptok ; yes, use :LP:
- clc
- ret
- CRF1: call cropsr
- jnc CRF2
- call exfisr
- jmp short OP5
- CRF2: call crfile ; create file
- mov bx,3 ; mode for OPEN & error return code
- mov temp+2,bx ; error return code
- jmp short OP4
-
- cropsr proc
- mov si,dx
- mov di,offset kermtmp ; is it "$kermit$.tmp"?
- mov cx,size kermtmp
- repe cmpsb
- jne CROP1
- mov bx,scfitok ; yes, use token for scratch file
- mov temp,bx ; save it
- stc
- ret
- CROP1: mov si,offset temp+3
- call z2rmx ; ASCIIZ string to temp+3
- mov di,offset temp+2 ; setup di
- mov [di],al ; length makes it RMX string at temp+2
- clc
- ret
- cropsr endp
-
- creat2 endp
-
- open2 proc
- call save
- sub ah,ah ; convert DOS mode to RMX
- inc ax
- mov temp,ax ; save mode
- mov ax,ds
- mov es,ax
- mov si,dx
- mov di,offset dotini ; is it MSKERMIT.INI?
- mov cx,size dotini
- repe cmpsb
- jne OP1 ; no
- mov ax,initok ; yes, initok's already attached
- jmp short OP3
- OP1: call cropsr
- jnc OP2
- call rewind
- jmp short OP5
- OP2: call atfile
- OP3: mov temp+2,2 ; error return code
- mov bx,temp ; get mode
- OP4: mov temp,ax ; save token
- mov cx,2 ; call rqsopen(token,mode,2,@status)
- call opfile
- OP5: call rstr
- mov ax,temp ; return token to caller in ax
- mov bx,temp+2 ; get error return code
- jmp short CRYFLG
- open2 endp
-
- close2 proc
- mov bx,savebx ; savebx has file token
- cmp bx,scfitok ; if it's the scratch file,
- je CL1 ; don't you dare!
- cmp bx,lptok ; :LP:, neither
- je CL1
- call save
- mov bx,savebx
- call delcon ; delete connection
- call rstr
- mov bx,6 ; error flag, if necessary
- jmp short CRYFLG
- CL1: ret
- close2 endp
-
- readf2 proc
- call save
- mov ax,savebx ; savebx has file token
- mov bx,dx ; nbyt=rqsreadmove(token,@buf,cnt,@status)
- call reader
- RF1: mov temp,ax ; save # bytes read
- call rstr
- mov ax,temp ; return to caller in ax
- mov bx,6 ; error flag, if necessary
- jmp short CRYFLG
- readf2 endp
-
- write2 proc
- call save
- mov bx,savebx ; savebx has file token
- test bx,bx ; is it magic token 0 (CI)?
- jz WRT1 ; yes, let fail gracefully
- cmp bx,4 ; other magic tokens?
- ja WRT1 ; no
- shl bx,1 ; yes, lookup real token
- mov bx,citok[bx]
- WRT1: mov ax,bx
- mov bx,dx ; nbyt=rqswritemove(token,@buf,cnt,@status)
- call writer
- jmp RF1
- write2 endp
-
- del2 proc
- call save
- mov ax,ds
- mov es,ax
- mov si,offset temp+1 ; ASCIIZ string @ds:dx to temp+1
- call z2rmx
- mov bx,offset temp
- mov byte ptr[bx],al ; length makes it RMX string at temp
- push ds ; call rqsdeletefile(@temp,@status)
- push bx
- push ds
- %pushv(offset status)
- call rqsdeletefile
- call rstr
- mov bx,2 ; error return code
- CRYFLG: clc
- cmp status,0 ; OK?
- je CFLG1 ; yes
- stc
- mov ax,bx ; & return error code
- CFLG1: ret
- del2 endp
-
- lseek proc
- call save
- mov bx,savebx ; savebx has file token
- push bx ; save for get con. status
- add al,2 ; convert DOS mode to RMX
- cbw
- call seek
- pop bx
- call gconsta ; getconnectionstatus puts file ptr
- call rstr ; in temp+4 & 6
- mov ax,temp+4 ; dx:ax are file pointer
- mov dx,temp+6
- mov bx,6 ; error flag, if necessary
- jmp CRYFLG
- lseek endp
-
- alloc proc
- call save
- mov ax,savebx ; savebx has # paragraphs
- cmp ax,1000h ; is it 65K?
- jl AL2 ; <65K, it's OK
- jne AL1 ; >65K, too much
- sub ax,ax ; =65K, use 0 for full segment
- jmp short AL2
- AL1: mov status,ax ; force error
- jmp short AL3
- AL2: mov cl,4 ; convert paragraphs to bytes
- shl ax,cl
- push ax ; seg_base=rqcreatesegment(#bytes,@status)
- push ds
- %pushv(offset status)
- call rqcreatesegment
- mov temp,ax ; save
- AL3: call rstr
- mov ax,temp ; restore seg_base return param
- mov bx,8 ; error return code
- jmp CRYFLG
- alloc endp
-
- gcd proc
- mov byte ptr[si],0 ; return null string @ds:si
- clc
- ret
- gcd endp
-
- setblk proc
- ret
- setblk endp
-
- PUSHCMD: ; actually, part of exec
- mov dx,offset pushmsg ; for now, say "no pushing"
- call prstr ; but here's the spot to implement later
- call rstr
- mov ax,11
- stc
- ret
-
- exec proc
- call save
- mov bx,savebx ; saved bx
- mov di,es:[bx+2] ; command tail pointer to es:di
- mov es,es:[bx+4]
- sub cx,cx
- mov cl,es:[di] ; if command tail length is 0, it's PUSH
- jcxz PUSHCMD
- inc di
- mov al,' '
- repne scasb ; scan past DOSisms
- repe scasb
- dec di ; 1st non-blank char of command
- mov bx,di
- mov dx,cx ; bx is ptr, dx is count
- mov al,'>' ; if '>' appears, Kermit's asking for
- repne scasb ; redirected output
- mov ax,cmdtok ; if not, use ordinary cmd token
- jne EX1 ; ne = no redirection
- sub dx,cx ; reduce count by chars from '>' to end
- dec dx
- push bx
- push dx
- push es
- call exfisr ; rewind & truncate scratch file
- pop es
- pop dx
- pop bx
- mov ax,rcmdtok ; use redirected cmd token
-
- EX1: mov temp+100,ax ; save cmd token
- mov si,offset typecmd ; is it 'TYPE'?
- mov di,bx
- mov cx,size typecmd
- repe cmpsb
- jne EX2 ; ne = no
- mov [bx],'oc' ; replace w/'COPY'
- mov [bx+2],'yp'
- jmp short EX4
-
- EX2: mov si,offset delcmd ; is it 'DEL'?
- mov di,bx
- mov cl,size delcmd
- repe cmpsb
- jne EX3 ; ne = no
- sub dx,size delcmd ; construct RMX DELETE command @delrmx
- mov cx,dx
- mov al,' '
- repe scasb
- dec di
- inc cx
- mov dx,cx
- add dx,size delrmx
- push ds
- push es
- pop ds
- pop es
- mov si,di
- mov di,offset deltail
- rep movsb
- mov si,offset delrmx
- jmp short EX5
-
- EX3: mov si,offset chkdsk
- mov di,bx
- mov cl,size chkdsk
- repe cmpsb
- jne EX4
- mov bx,offset dirfree ; yes, use 'dir $ free' as command
- mov dx,size dirfree
- mov cx,ds
- mov es,cx
-
- EX4: push ds ; swap ds & es
- push es
- pop ds
- pop es
- mov si,bx
- EX5: mov di,offset temp ; move command to temp
- mov ax,dx
- stosb
- mov cx,dx
- rep movsb
- push es ; restore ds
- pop ds
- mov ax,temp+100 ; command token
- cmp ax,rcmdtok ; if output's going to scratch file
- je EX6 ; bypass fussing w/:TERM:
-
- mov ax,citok ; shut down citsk
- call aclose
- mov ax,citok ; reopen
- mov bx,3
- call aopen
-
- call flushci ; wait for output to :TERM: to finish
- mov bx,offset savspec ; ping back to user's connection &
- push word ptr[bx+2] ; terminal attributes
- mov word ptr[bx+2],2
- mov ax,cotok
- mov cx,5
- call special
- mov ax,citok
- mov bx,offset savspec
- mov cx,5
- call aspcl
- pop savspec+2
-
- EX6: mov ax,temp+100 ; command token
- push ax ; save it
- mov bx,offset temp ; call rqcsendcommand
- mov cx,offset temp+100 ; (token,@temp,@temp+100,@status)
- call sendcmd
- pop ax ; command token
- cmp ax,rcmdtok ; if it went to scratch file,
- je EX7 ; don't mess w/:TERM:
-
- push cx ; save status
- call flushci ; wait for completion of cmd's output
- mov ax,cotok ; pong attr's back to Kermit's
- mov bx,offset termatt
- mov cx,5
- call special
- mov ax,citok
- mov bx,offset termatt
- mov cx,5
- call aspcl
-
- mov ax,cimbx ; restart citsk
- mov bx,ax
- call sendms
- pop cx ; restore status
-
- EX7: cmp cx,83h ; is it E$CONTINUED
- je EX8 ; yes, return w/carry clear
- or cx,temp+100 ; sendcmd status OR status from command
- jcxz EX8 ; jump if OK
- call rstr
- mov ax,2 ; return error code w/carry set
- stc
- ret
- EX8: call rstr
- clc
- ret
-
- exfisr proc ; rewind & truncate scratch file
- mov bx,scfitok
- push bx ; save for truncate
- call rewind ; rewind scratch file
- push ds ; call rqstruncatefile(scfitok,@status)
- %pushv(offset status)
- call rqstruncatefile
- ret
- exfisr endp
-
- flushci proc
- mov ax,citok ; this is necessary to wait for completion
- mov bx,offset flush ; of output to :TERM: for fast systems
- mov cx,size flush
- sub dx,dx
- call awrite
- mov ax,citok
- mov bx,offset cobuf1
- mov cx,cobufl
- mov dx,tmbox
- call aread
- mov ax,citok
- mov bx,tmbox
- call waitio
- ret
- flushci endp
- exec endp
-
- exit proc
- sub ah,ah ; convert DOS exit code to RMX
- test ax,ax
- jz X1
- mov ah,40h ; put in user range, if non-0
- X1: mov xitcode,ax
- jmp stop
- exit endp
-
- first2 proc
- call save
- mov si,dx ; ds:dx points to ASCIIZ file name
- mov ax,ds
- mov es,ax
- mov di,offset kermtmp ; is it "$kermit$.tmp"?
- mov temp+100,di
- mov cx,size kermtmp
- mov temp+102,cx
- repe cmpsb
- jne FST2
- mov bx,scfitok ; yes, fill in DTA. For scratch file,
- call gconsta ; getconnectionstatus to temp
- mov ax,temp+4 ; bx:ax are file pointer,
- mov bx,temp+6 ; which is length of scratch file
- FST1: mov di,kbuf
- mov [di+1ah],ax ; lo file size to DTA
- mov [di+1ch],bx ; hi file size to DTA
- mov byte ptr [di+15h],0 ; clear DTA's attribute field
- add di,1eh ; point to DTA's file name field
- mov si,temp+100
- mov cx,temp+102
- rep movsb
- call rstr
- mov bx,2
- jmp CRYFLG
-
- FST2: mov si,dx
- mov di,offset dotini ; is it MSKERMIT.INI?
- mov temp+100,di
- mov cx,size dotini
- mov temp+102,cx
- sub bx,bx
- repe cmpsb
- mov ax,inisize
- je FST1 ; yes, initok's already attached
-
- mov temp+100,2
- mov si,dx
- cmp word ptr[si],002ch ; is it ',',0?
- je NXT1 ; eq = yes, treat as next
-
- push es
- push dx
- call exfisr ; rewind & truncate scratch file
- pop dx
- pop es
-
- mov si,offset wcpath ; move file-spec to wcpath, length to ax
- call z2rmx
- mov bx,ax
- add al,3
- mov wccmd,al ; + 3 for 'wc ' makes RMX string
- mov si,dx ; point to file-spec
- mov cx,bx ; length
-
- FST3: lodsb ; scan for wc chars, if any goto FST4
- cmp al,'*'
- je FST4
- cmp al,'?'
- je FST4
- cmp al,','
- je FST4
- loop FST3
-
- mov si,dx ; no need for wc, next can handle it
- mov di,offset wcpath+1 ; if we move it over 1 byte
- mov cx,bx
- rep movsb
- jmp short NXT3
-
- FST4: mov si,dx
- add si,bx ; point to end
- dec si ; backup over zero byte
- call bakscan ; find rightmost path separater
- cmp al,'\' ; is it \?
- jne FST5
- call rstr ; yes, force error
- mov ax,2 ; it's a DOSism we can do without
- stc
- ret
-
- FST5: mov ax,rcmdtok ; call rqcsendcommand
- mov bx,offset wccmd ; (rcmdtok,@wccmd,@temp,@status)
- mov cx,offset temp
- call sendcmd
-
- mov bx,scfitok ; rewind scratch file
- call rewind
- mov nxtflg,0
- jmp short NXT1 ; let next finish up
- first2 endp
-
- next2 proc
- call save
- mov temp+100,18 ; error return code
- cmp nxtflg,0 ; was next called before 1st,
- jne NXT4 ; or after no more? ne = yes
-
- NXT1: mov bx,offset wcpath ; place to stash file name string
- mov byte ptr[bx],0 ; empty
- NXT2: inc bx ; bump count
- push bx
- mov ax,scfitok ; read 1 from scratch
- mov cx,1
- call reader
- test ax,ax
- pop bx
- jz NXT4 ; 0 = EOF
- cmp byte ptr[bx],lf
- jne NXT2 ; loop 'til EOL
-
- sub bx,offset wcpath+2 ; bx = length file name
- NXT3: mov di,offset wcpath
- mov [di],bl ; RMX string @di
- call gfilsta ; does it exist?
- jcxz NXT5 ; 0 = yes
- NXT4: mov nxtflg,1 ; mark no more next w/o 1st 1st
- call rstr
- mov ax,temp+100 ; return error code
- stc
- ret
-
- NXT5: mov di,kbuf
- mov [di+15h],bl ; directory attribute to DTA
- mov [di+1ah],ax ; low file size
- mov [di+1ch],dx ; high file size
- mov bl,byte ptr wcpath
- sub bh,bh ; bx = length file name stirng
- lea si,wcpath[bx] ; point to end
- call bakscan ; separate path/file name
- mov cx,bx ; cx = file name length
- add di,1eh ; DTA file name field ptr
- mov ax,ds ; si points to file name, move it
- mov es,ax
- rep movsb
- mov [di],cl ; make ASCIIZ
- call rstr
- clc
- ret
- next2 endp
-
- save proc ; save regs
- pop bx
- push es
- push si
- push di
- push dx
- push cx
- push ax
- jmp bx
- save endp
-
- rstr proc ; restore regs
- pop bx
- pop ax
- pop cx
- pop dx
- pop di
- pop si
- pop es
- jmp bx
- rstr endp
-
- setexcp proc
- push ds ; call rqsetexceptionhandler(@xcepinf,@status)
- %pushv(offset xcepinf)
- push ds
- %pushv(offset status)
- call rqsetexceptionhandler
- ret
- setexcp endp
-
- crtsk proc ; ax=rqcreatetask(0,cs:bx,ds,0:0,300h,0,@status)
- sub cx,cx ; bx is start address
- push cx
- push cs
- push bx
- push ds
- push cx
- push cx
- %pushv(300h)
- push cx
- push ds
- %pushv(offset status)
- call rqcreatetask
- ret
- crtsk endp
-
- crmbx proc ; ax=rqcreatemailbox(0,@status)
- %pushv(0)
- push ds
- %pushv(offset status)
- call rqcreatemailbox
- ret
- crmbx endp
-
- crsema proc
- sub ax,ax ; ax=rqcreatesemaphore(0,1,0,@status)
- push ax
- inc ax
- push ax
- dec ax
- push ax
- push ds
- %pushv(offset status)
- call rqcreatesemaphore
- ret
- crsema endp
-
- atfile proc ; ax=rqsattachfile(ds:di,@status)
- push ds ; ds:di is path ptr
- push di
- push ds
- %pushv(offset status)
- call rqsattachfile
- ret
- atfile endp
-
- crfile proc ; ax=rqscreatefile(ds:di,@status)
- push di ; ds:di is path ptr. save di
- push ds
- push di
- push ds
- %pushv(offset status)
- call rqscreatefile
- pop di ; restore di
- ret
- crfile endp
-
- opfile proc ; call rqsopen(ax,bx,cx,@status)
- push ax ; token
- push bx ; mode
- push cx ; number of buffers
- push ds
- %pushv(offset status)
- call rqsopen
- ret
- opfile endp
-
- clfile proc ; call rqsclose(ax,@siostat)
- push ax ; token
- push ds
- %pushv(offset siostat)
- call rqsclose
- ret
- clfile endp
-
- delcon proc ; call rqsdeleteconnection(bx,@status)
- push bx ; token
- push ds
- %pushv(offset status)
- call rqsdeleteconnection
- ret
- delcon endp
-
- special proc ; call rqsspecial(ax,cx,ds:bx,0,@status)
- push ax ; token
- push cx ; function
- push ds
- push bx ; data ptr
- sub ax,ax
- push ax
- push ax
- push ds
- %pushv(offset status)
- call rqsspecial
- ret
- special endp
-
- reader proc ; ax=rqsreadmove(ax,ds:bx,cx,@status)
- push ax ; token
- push ds
- push bx ; buffer ptr
- push cx ; number of bytes
- push ds
- %pushv(offset status)
- call rqsreadmove
- ret
- reader endp
-
- writer proc ; ax=rqswritemove(ax,ds:bx,cx,@status)
- push ax ; token
- push ds
- push bx ; buffer ptr
- push cx ; number of bytes
- push ds
- %pushv(offset status)
- call rqswritemove
- ret
- writer endp
-
- rewind proc
- mov ax,2 ; setup so seek positions to BOF
- sub cx,cx
- mov dx,cx
-
- seek proc
- push bx ; call rqsseek(token,mode,count,@status)
- push ax
- push cx
- push dx
- push ds
- %pushv(offset status)
- call rqsseek
- ret
- seek endp
- rewind endp
-
- lookup proc ; ax=rqlookupobject(ax,ds:bx,0,@status)
- push ax ; job token
- push ds ; @name
- push bx
- push cx ; time limit
- push ds
- %pushv(offset status)
- call rqlookupobject
- ret
- lookup endp
-
- sdefpfx proc ; call rqsetdefaultprefix(cx,ax,@status)
- push cx ; job token
- push ax ; prefix token
- push ds
- %pushv(offset status)
- call rqsetdefaultprefix
- ret
- sdefpfx endp
-
- crcmdco proc ; ax=rqccreatecommandconnection(ax,bx,cx,@status)
- push ax ; input token
- push bx ; output token
- push cx ; flag
- push ds
- %pushv(offset status)
- call rqccreatecommandconnection ; can you believe this shit?
- ret
- crcmdco endp
-
- sendcmd proc ; call rqcsendcommand(ax,ds:bx,ds:cx,@status)
- push ax ; command connection token
- push ds
- push bx ; pointer to command
- push ds
- push cx ; pointer to command exception
- push ds
- %pushv(offset status)
- call rqcsendcommand
- push cx ; save status
- mov ax,citok
- mov bx,offset sigpair
- mov cx,6
- call aspcl ; restore ^C trap
- pop cx ; restore status
- ret
- sendcmd endp
-
- z2rmx proc ; copies ASCIIZ @ds:dx to si, returns count in ax
- mov di,dx
- mov cx,0ffffh
- sub ax,ax
- repne scasb
- neg cx
- add cx,0fffeh
- mov ax,cx ; ax=cx= # of bytes
- mov di,si
- mov si,dx
- rep movsb
- ret
- z2rmx endp
-
- bakscan proc ; finds path part & file name part
- std ; bx=string size, si points to EOstring
- mov cx,bx
- BSC1: lodsb
- cmp al,':'
- je BSC2
- cmp al,'/'
- je BSC2
- cmp al,'^'
- je BSC2
- loop BSC1
- dec si
- BSC2: inc si
- inc si ; si point to file name
- cld
- sub bx,cx ; bx=size file name, cx=size path
- ret ; al=separator
- bakscan endp
-
- aopen proc ; call rqaopen(ax,bx,3,0,@status)
- push ax ; token
- push bx ; mode
- %pushv(3)
- %pushv(0)
- push ds
- %pushv(offset status)
- call rqaopen
- ret
- aopen endp
-
- aclose proc
- push ax ; call rqaclose(ax,cx,@siostat)
- push cx
- push ds
- %pushv(offset siostat)
- call rqaclose
- ret
- aclose endp
-
- aread proc ; call rqaread(ax,ds:bx,cx,dx,@siostat)
- push ax
- push ds
- push bx ; buffer ptr
- push cx ; count
- push dx ; response mailbox
- push ds
- %pushv(offset siostat)
- call rqaread
- ret
- aread endp
-
- awrite proc ; call rqawrite(ax,ds:bx,cx,dx,@siostat)
- push ax
- push ds
- push bx ; buffer ptr
- push cx ; count
- push dx ; response mailbox
- push ds
- %pushv(offset siostat)
- call rqawrite
- ret
- awrite endp
-
- aspcl proc ; call rqaspecial(ax,cx,ds:bx,tmbox,@siostat)
- push ax ; token
- push cx ; function
- push ds
- push bx ; ioparm ptr
- push tmbox
- push ds
- %pushv(offset siostat)
- call rqaspecial
- mov ax,tmbox
- mov bx,0ffffh
- call rcvmsg ; ax=rqreceivemessage(tmbox,0ffffh,@ignore,@siostat)
- call delseg
- ret
- aspcl endp
-
- waitio proc ; ax=rqwaitio(ax,bx,0ffffh,@status)
- push ax ; token
- push bx ; response mailbox
- %pushv(0ffffh)
- push ds
- %pushv(offset status)
- call rqwaitio
- ret
- waitio endp
-
- sendms proc ; call rqsendmessage(ax,bx,0,@status)
- push ax ; mailbox token
- push bx ; object to send
- %pushv(0)
- push ds
- %pushv(offset status)
- call rqsendmessage
- cld
- ret
- sendms endp
-
- rcvmsg proc
- pop bp ; ax=rqreceivemessage(tmbox,0ffffh,@ignore,@siostat)
- push ax ; mail box token
- push bx ; time limit
- push ds
- %pushv(offset ignore)
- push ds
- %pushv(offset siostat)
- call rqreceivemessage
- jmp bp
- rcvmsg endp
-
- rcvun proc ; call rqreceiveunits(ax,1,0ffffh,@ccstat)
- pop bp
- push ax ; semaphore token
- %pushv(1) ; units
- %pushv(0ffffh) ; time limit
- push ds
- %pushv(offset ccstat)
- call rqreceiveunits
- jmp bp
- rcvun endp
-
- delseg proc ; call rqdeletesegment(ax,@status)
- push ax
- push ds
- %pushv(offset siostat)
- call rqdeletesegment
- ret
- delseg endp
-
- gconsta proc
- push bx ; call rqsgetconnectionstatus(token,@temp,@status)
- push ds
- %pushv(offset temp)
- push ds
- %pushv(offset status)
- call rqsgetconnectionstatus
- ret
- gconsta endp
-
- gfilsta proc
- push ds ; call rqsgetfilestatus(ds:di,@temp,@status)
- push di ; path ptr
- push ds
- %pushv(offset temp)
- push ds
- %pushv(offset status)
- call rqsgetfilestatus
- jcxz GFIL1
- ret
- GFIL1: mov bx,cx
- cmp byte ptr temp+9,0ffh ; is it a named file?
- je GFIL2
- mov ax,cx ; no, setup for zero length
- mov dx,cx
- ret
- GFIL2: cmp byte ptr temp+38,8 ; is it a directory?
- je GFIL3 ; eq = no
- mov bl,10h ; yes, get DOS directory attribute
- GFIL3: mov ax,temp+54 ; low file size
- mov dx,temp+56 ; high file size
- ret
- gfilsta endp
-
- code ends
- end begin, ds:datas, ss:stack
-